package datastruct.list.impl;

import datastruct.list.inter.IListConsumer;
import datastruct.list.inter.IExpected;
import datastruct.list.inter.IJoList;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.Stack;
import java.util.concurrent.ConcurrentLinkedDeque;
import java.util.concurrent.atomic.AtomicInteger;

public class JoList implements IJoList {

    private ConcurrentLinkedDeque<String> deque;
    private AtomicInteger listSize;

    public JoList() {
        deque = new ConcurrentLinkedDeque<>();
        listSize = new AtomicInteger(0);
    }

    public static JoList makeList() {
        return new JoList();
    }

    @Override
    public void add(String val) {
        deque.add(val);
        listSize.getAndIncrement();
    }

    public void addFirst(String val) {
        deque.addFirst(val);
        listSize.getAndIncrement();
    }

    @Override
    public String get(int index) {
        if (index < 0 || index >= Len()) {
            return null;
        }
        int i = 0;
        for (String obj : deque) {
            if (i == index) {
                return obj;
            }
            i++;
        }
        return null;
    }

    @Override
    public boolean set(int index, String val) {
        if (index >= Len()) {
            return false;
        }
        // 先[0,index] 范围内的元素
        Stack<String> stack = new Stack<>();
        for (int i=0;i<index;i++) {
            stack.push(deque.removeFirst());
        }
        // 删除 index 处的元素
        deque.removeFirst();

        // 放入新元素
        deque.addFirst(val);

        // 把原有元素放回去
        while (!stack.isEmpty()) {
            deque.addFirst(stack.pop());
        }
        return true;
    }

    @Override
    public void insert(int index, String val, boolean isBefore) {
        // 先把 index 之前的所有元素拿出来
        Stack<String> temp = new Stack<>();
        if (!isBefore) {
            index++;
        }
        for (int i=0;i<index;i++) {
            temp.push(deque.removeFirst());
        }
        // 然后把 val 放到队头
        deque.addFirst(val);
        // 再把原有元素放入
        while (!temp.isEmpty()) {
            deque.addFirst(temp.pop());
        }
        listSize.getAndIncrement();
    }

    @Override
    public int Remove(String val, int count) {
        int i = 0;
        for (i = 0; i < count; i++) {
            if (deque.remove(val)) {
                listSize.getAndDecrement();
            } else {
                break;
            }
        }
        return i;
    }

    @Override
    public int RemoveFrom(int direction, int count, String target) {
        // 正向遍历
        Iterator<String> iterator = direction >= 0 ? deque.iterator() : deque.descendingIterator();
        int i = 0;
        while (i < count && iterator.hasNext()) {
            if (target.equals(iterator.next())) {
                deque.remove(target);
                listSize.getAndDecrement();
                i++;
            }
        }
        return i;
    }

    @Override
    public String RemoveFirst() {
        if (deque.isEmpty()) {
            return null;
        }
        listSize.getAndDecrement();
        return deque.removeFirst();
    }

    @Override
    public String RemoveLast() {
        if (deque.isEmpty()) {
            return null;
        }
        listSize.getAndDecrement();
        return deque.removeLast();
    }

    @Override
    public int Len() {
        return listSize.intValue();
    }

    @Override
    public void forEach(boolean desc, IListConsumer iConsumer) {
        AtomicInteger i = new AtomicInteger();
        if (desc) {
            Iterator<String> iterator = deque.descendingIterator();
            while (iterator.hasNext()) {
                String val = iterator.next();
                if (!iConsumer.consumer(i.get(), val)) {
                    return;
                }
                i.getAndIncrement();
            }
            return;
        }
        deque.forEach(instance -> {
            if (!iConsumer.consumer(i.get(), instance)) {
                return;
            }
            i.getAndIncrement();
        });
    }

    @Override
    public boolean contains(String obj) {
        return deque != null && deque.contains(obj);
    }

    @Override
    public String[] range(int start, int end) {
        ArrayList<String> ret = new ArrayList<>();
        forEach(false, new IListConsumer() {
            @Override
            public boolean consumer(int i, Object val) {
                if (i >= start && i < end) {
                    ret.add((String) val);
                }
                return true;
            }
        });
        return ret.toArray(new String[0]);
    }

    @Override
    public int indexOfVal(String obj) {
        Iterator<String> iterator = deque.iterator();
        int i = 0;
        while (iterator.hasNext()) {
            if (obj.equals(iterator.next())) {
                break;
            }
            i++;
        }
        return i;
    }

    public static void main(String[] args) {
        JoList ls = new JoList();
        ls.add("A");
        ls.add("B");
        ls.add("C");
        ls.add("D");

        int index = ls.indexOfVal("C");
        System.out.println(index);


    }
}
